import axios from "axios"
import { ElMessage } from "element-plus"
import { get, merge } from "lodash-es"
import { getToken } from "./cache/cookies"

/** 退出登录并强制刷新页面（会重定向到登录页） */
async function logout() {
  // 动态导入用户store，避免循环依赖
  const { useUserStore } = await import("@/store/modules/user")
  useUserStore().logout()
  location.reload()
}

/** 创建请求实例 */
function createService() {
  // 创建一个 axios 实例命名为 service
  const service = axios.create()
  // 请求拦截
  service.interceptors.request.use(
    (config) => config,
    // 发送失败
    (error) => Promise.reject(error)
  )
  // 响应拦截（可根据具体业务作出相应的调整）
  service.interceptors.response.use(
    (response) => {
      // apiData 是 api 返回的数据
      const apiData = response.data
      // 二进制数据则直接返回
      const responseType = response.request?.responseType
      if (responseType === "blob" || responseType === "arraybuffer") return apiData
      // 这个 code 是和后端约定的业务 code
      const code = apiData.code
      // 如果没有 code, 代表这不是项目后端开发的 api
      if (code === undefined) {
        ElMessage.error("非本系统的接口")
        return Promise.reject(new Error("非本系统的接口"))
      }
      switch (code) {
        case 200:
          // 本系统采用 code === 200 来表示没有业务错误
          return apiData
        case 401:
          // Token 过期时
          return logout()
        default:
          // 不是正确的 code
          ElMessage.error(apiData.message || "Error")
          return Promise.reject(new Error("Error"))
      }
    },
    (error) => {
      // status 是 HTTP 状态码
      const status = String(get(error, "response.status"))

      switch (status) {
        case '400':
          error.message = "参数异常"
          break
        case '401':
          // Token 过期时
          logout()
          break
        case '4001':
          error.message = "参数缺失"
          break
        case '403':
          error.message = "拒绝访问"
          break
        case '404':
          error.message = "请求地址出错"
          break
        case '408':
          error.message = "请求超时"
          break
        case '500':
          error.message = "系统异常"
          break
        case '501':
          error.message = "服务未实现"
          break
        case '5001':
          error.message = "用户名已存在"
          break
        case '5002':
          error.message = "用户未登录"
          break
        case '5003':
          error.message = "账号或密码错误"
          break
        case '5004':
          error.message = "用户不存在"
          break
        case '5005':
          error.message = "原密码输入错误"
          break
        case '502':
          error.message = "网关错误"
          break
        case '503':
          error.message = "服务不可用"
          break
        case '504':
          error.message = "网关超时"
          break
        case '505':
          error.message = "HTTP 版本不受支持"
          break
        default:
          // 如果没有匹配的状态码，尝试使用后端返回的错误信息
          error.message = error.response?.data?.message || "未知错误"
      }

      // 添加调试日志
      console.log('Error status:', status, 'Error message:', error.message)

      ElMessage.error(error.message)
      return Promise.reject(error)
    }
  )
  return service
}

/** 创建请求方法 */
function createRequest(service) {
  return function (config) {
    const token = getToken()
    const defaultConfig = {
      headers: {
        // 携带 Token
        Authorization: token ? `Bearer ${token}` : undefined,
        "Content-Type": "application/json"
      },
      timeout: 10000,
      baseURL: import.meta.env.VITE_BASE_API,
      data: {}
    }
    // 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig
    const mergeConfig = merge(defaultConfig, config)
    return service(mergeConfig)
  }
}

/** 用于网络请求的实例 */
const service = createService()
/** 用于网络请求的方法 */
export const request = createRequest(service)

// 兼容旧版本的 HTTP 方法封装
const http = {
  get(url, params = {}) {
    return request({
      url,
      method: 'get',
      params
    })
  },

  post(url, data = {}) {
    return request({
      url,
      method: 'post',
      data
    })
  },

  put(url, data = {}) {
    return request({
      url,
      method: 'put',
      data
    })
  },

  delete(url, params = {}) {
    return request({
      url,
      method: 'delete',
      params
    })
  },

  upload(url, formData) {
    return request({
      url,
      method: 'post',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  }
}

export default http

